package org.bluesky.framework.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.bluesky.framework.ResponseResult;
import org.bluesky.framework.constants.SystemConstants;
import org.bluesky.framework.dto.AddRoleDto;
import org.bluesky.framework.dto.UpdateRoleDto;
import org.bluesky.framework.entity.Menu;
import org.bluesky.framework.entity.Role;
import org.bluesky.framework.entity.RoleMenu;
import org.bluesky.framework.mapper.RoleMapper;
import org.bluesky.framework.service.MenuService;
import org.bluesky.framework.service.RoleMenuService;
import org.bluesky.framework.service.RoleService;
import org.bluesky.framework.utils.BeanCopyUtils;
import org.bluesky.framework.utils.SecurityUtils;
import org.bluesky.framework.vo.MenuRoleVo;
import org.bluesky.framework.vo.PageVo;
import org.bluesky.framework.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色信息表(Role)表服务实现类
 *
 * @author makejava
 * @since 2023-02-20 20:38:00
 */
@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private MenuService menuService;
    @Autowired
    private RoleMenuService roleMenuService;
    @Override
    public List<String> selectRoleKeyByUserId(Long id) {
        //判断是否是管理员，如果是返回集合中只需要有admin
        if(SecurityUtils.isAdmin()){
            List<String> roleKeys = new ArrayList<>();
            roleKeys.add("admin");
            return roleKeys;
        }
        //否则查询用户所具有的角色信息
        return getBaseMapper().selectRoleKeyByUserId(id);
    }

    @Override
    public ResponseResult getRoleList(Integer pageNum, Integer pageSize, String roleName, String status) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.hasText(roleName)){
            queryWrapper.like(Role::getRoleName,roleName);
        }
        if(StringUtils.hasText(status)){
            queryWrapper.eq(Role::getStatus,status);
        }
        queryWrapper.orderByAsc(Role::getRoleSort);
        Page<Role> page = new Page<>(pageNum,pageSize);
        page(page, queryWrapper);
        List<Role> roles = page.getRecords();
        List<RoleVo> roleVos = BeanCopyUtils.copyBeanList(roles, RoleVo.class);
        PageVo pageVo = new PageVo(roleVos,page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public List<MenuRoleVo> treeMenuSelect() {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getParentId, 0L);
        List<Menu> menus = menuService.list(queryWrapper);
        List<MenuRoleVo> menuRoleVos = BeanCopyUtils.copyBeanList(menus, MenuRoleVo.class);
        List<MenuRoleVo> vos = buildTreeMenu(menuRoleVos);
        return vos;
    }

    private List<MenuRoleVo> buildTreeMenu(List<MenuRoleVo> menus){
        List<MenuRoleVo> menuRoleList = menus.stream()
                .peek(menuRoleVo -> {
                    List<MenuRoleVo> children = getChildren(menuRoleVo);
                    menuRoleVo.setChildren(children);
                    menuRoleVo.setLabel(menuRoleVo.getMenuName());
                    buildTreeMenu(children);
                })
                .collect(Collectors.toList());
        return menuRoleList;
    }
    private List<MenuRoleVo> getChildren(MenuRoleVo menuRoleVo){
        Long id = menuRoleVo.getId();
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getParentId, id);
        List<Menu> list = menuService.list(queryWrapper);
        List<MenuRoleVo> children = BeanCopyUtils.copyBeanList(list, MenuRoleVo.class);
        return children;
    }

    @Override
    @Transactional
    public ResponseResult addRole(AddRoleDto addRoleDto) {
        Role role = BeanCopyUtils.copyBean(addRoleDto,Role.class);
        List<Long> menuIds = addRoleDto.getMenuIds();
        save(role);
        for(Long menuId:menuIds){
            roleMenuService.save(new RoleMenu(role.getId(), menuId));
        }
        return ResponseResult.okResult();
    }

    @Override
    @Transactional
    public ResponseResult updateRoleById(UpdateRoleDto updateRoleDto) {
        Role role = BeanCopyUtils.copyBean(updateRoleDto, Role.class);
        updateById(role);
        //移除以前的
        roleMenuService.deleteRoleMenuByRoleId(role.getId());
        //添加现在的
        List<Long> menuIds = updateRoleDto.getMenuIds();
        List<RoleMenu> roleMenus = menuIds.stream()
                .map(menuId -> new RoleMenu(role.getId(), menuId))
                .collect(Collectors.toList());
        roleMenuService.saveBatch(roleMenus);
        return ResponseResult.okResult();
    }

    @Override
    @Transactional
    public ResponseResult deleteRoleById(Long id) {
        removeById(id);
        roleMenuService.deleteRoleMenuByRoleId(id);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult rolesStatusNormal() {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getStatus, SystemConstants.STATUS_NORMAL);
        List<Role> roles = list(queryWrapper);
        return ResponseResult.okResult(roles);
    }
}

